package com.ycy.listener;

import org.flowable.bpmn.model.FlowElement;
import org.flowable.common.engine.api.delegate.event.FlowableEngineEvent;
import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType;
import org.flowable.common.engine.api.delegate.event.FlowableEvent;
import org.flowable.common.engine.api.delegate.event.FlowableEventListener;
import org.flowable.common.engine.impl.cfg.TransactionState;
import org.flowable.common.engine.impl.event.FlowableEntityEventImpl;
import org.flowable.engine.ProcessEngine;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.event.impl.FlowableActivityEventImpl;
import org.flowable.engine.delegate.event.impl.FlowableEntityWithVariablesEventImpl;
import org.flowable.engine.delegate.event.impl.FlowableMultiInstanceActivityEventImpl;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.repository.ProcessDefinitionQuery;
import org.flowable.task.api.Task;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import org.flowable.task.service.impl.persistence.entity.TaskEntityImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

public class YcyFlowableListener implements FlowableEventListener {

  Logger logger = LoggerFactory.getLogger(this.getClass());

  ProcessEngine processEngine;

  public YcyFlowableListener() {
  }

  public YcyFlowableListener(ProcessEngine processEngine) {
    this.processEngine = processEngine;
  }

  public ProcessEngine getProcessEngine() {
    return processEngine;
  }

  public void setProcessEngine(ProcessEngine processEngine) {
    this.processEngine = processEngine;
  }

  @Override
  public void onEvent(FlowableEvent flowableEvent) {

    if (flowableEvent.getType().equals(FlowableEngineEventType.MULTI_INSTANCE_ACTIVITY_STARTED)) {
      FlowableMultiInstanceActivityEventImpl activityEvent = (FlowableMultiInstanceActivityEventImpl) flowableEvent;
      DelegateExecution execution = activityEvent.getExecution();
      String processInstanceId = execution.getProcessInstanceId();
      FlowElement flowElement = execution.getCurrentFlowElement();
      String flowElementName = flowElement.getName();
      String documentation = flowElement.getDocumentation();
      execution.setVariable(flowElementName, "初始化一个值");
      logger.info("COMMITTED 通知事件 {} --> procInstId：{},{}", flowableEvent.getType(), processInstanceId, flowElementName);
    } else if (flowableEvent.getType().equals(FlowableEngineEventType.ACTIVITY_COMPLETED)
            || flowableEvent.getType().equals(FlowableEngineEventType.MULTI_INSTANCE_ACTIVITY_COMPLETED_WITH_CONDITION)) {
      /*
       * 节点发生流转，才会触发。
       */
      FlowableActivityEventImpl flowableActivityEvent = (FlowableActivityEventImpl) flowableEvent;
      String processInstanceId = flowableActivityEvent.getProcessInstanceId();

      logger.info("COMMITTED 通知事件 {} --> procInstId：{},{}", flowableEvent.getType()
              , processInstanceId, ((FlowableActivityEventImpl) flowableEvent).getActivityId());
    } else if (flowableEvent.getType().equals(FlowableEngineEventType.ENTITY_DELETED)) {

      // FlowableEntityEventImpl 和task_create的类不一样，注意
      if (flowableEvent.getClass().equals(org.flowable.engine.delegate.event.impl.FlowableEntityEventImpl.class)) {
        Object en = ((org.flowable.engine.delegate.event.impl.FlowableEntityEventImpl) flowableEvent).getEntity();
        if (en.getClass().equals(TaskEntityImpl.class)) {
          TaskEntityImpl taskEntity = (TaskEntityImpl) en;
          logger.info("COMMITTED 通知事件 {} --> procInstId：{},{},{}"
                  , flowableEvent.getType()
                  , taskEntity.getProcessInstanceId()
                  , taskEntity.getAssignee()
                  , flowableEvent);
        }
      }

      // 通过service删除的事件类，FlowableEntityEventImpl 和task_create的类不一样，注意
      if (flowableEvent.getClass().equals(org.flowable.common.engine.impl.event.FlowableEntityEventImpl.class)) {
        Object en = ((org.flowable.common.engine.impl.event.FlowableEntityEventImpl) flowableEvent).getEntity();
        if (en.getClass().equals(TaskEntityImpl.class)) {
          TaskEntityImpl taskEntity = (TaskEntityImpl) en;
          logger.info("COMMITTED 通知事件 {} --> procInstId：{},{},{}"
                  , flowableEvent.getType()
                  , taskEntity.getProcessInstanceId()
                  , taskEntity.getAssignee()
                  , flowableEvent);
        }
      }
    }

//    logger.info("通知事件 --> {}", flowableEvent);
//    // 任务创建
//    if (flowableEvent.getType().equals(FlowableEngineEventType.TASK_CREATED)) {
//      if (flowableEvent instanceof FlowableEntityEventImpl) {
//        Object en = ((FlowableEntityEventImpl) flowableEvent).getEntity();
//        if (en instanceof TaskEntityImpl) {
//          TaskEntityImpl taskEntity = (TaskEntityImpl) en;
//          logger.info("--> " + flowableEvent.getType() + " " + taskEntity.getProcessInstanceId() + " " + taskEntity.getExecutionId() + " " + taskEntity);
//        }
//      } else {
//        logger.info("--> " + flowableEvent.getType() + " " + flowableEvent);
//      }
//      //抛出一个异常 触发事务回滚
////          throw new RuntimeException();
//    }
//
//    //任务完成
//    if (flowableEvent.getType().equals(FlowableEngineEventType.TASK_COMPLETED)) {
//      if (flowableEvent.getClass().equals(FlowableEntityWithVariablesEventImpl.class)) {
//        FlowableEntityWithVariablesEventImpl taskCompletedEvent =
//                (FlowableEntityWithVariablesEventImpl) flowableEvent;
//        logger.info("--> " + taskCompletedEvent.getType() + " " + taskCompletedEvent.getProcessInstanceId() + " " + taskCompletedEvent.getExecutionId() + " " + taskCompletedEvent.getEntity());
//
//        //获取流程定义
//        List<ProcessDefinition> list = this.processEngine.getRepositoryService().createProcessDefinitionQuery().processDefinitionId(taskCompletedEvent.getProcessDefinitionId()).list();
//        System.out.println(list);
//      } else if (flowableEvent instanceof org.flowable.engine.delegate.event.impl.FlowableEntityEventImpl) {
//        org.flowable.engine.delegate.event.impl.FlowableEntityEventImpl flowableEvent1
//                = (org.flowable.engine.delegate.event.impl.FlowableEntityEventImpl) flowableEvent;
//        logger.info("--> " + flowableEvent.getType() + " " + flowableEvent1.getEntity());
//
//        //获取流程定义
//        List<ProcessDefinition> list = this.processEngine.getRepositoryService().createProcessDefinitionQuery().processDefinitionId(flowableEvent1.getProcessDefinitionId()).list();
//        System.out.println(list);
//      } else {
//        logger.info("--> " + flowableEvent.getType() + " " + flowableEvent);
//      }
//    }
//
//    if (flowableEvent.getType().equals(FlowableEngineEventType.ENTITY_DELETED)) {
//      /*
//        ENTITY_DELETED class org.flowable.common.engine.impl.event.FlowableEntityEventImpl - ENTITY_DELETED
//        ENTITY_DELETED class org.flowable.engine.delegate.event.impl.FlowableEntityEventImpl - ENTITY_DELETED
//       */
//      if (flowableEvent instanceof org.flowable.engine.delegate.event.impl.FlowableEntityEventImpl) {
//        org.flowable.engine.delegate.event.impl.FlowableEntityEventImpl flowableEvent1
//                = (org.flowable.engine.delegate.event.impl.FlowableEntityEventImpl) flowableEvent;
//        logger.info("--> " + flowableEvent.getType() + " " + flowableEvent1.getExecutionId() + " " + flowableEvent1.getEntity());// Execution 和 Task[id=2523, name=任务1]
//
//
//        //获取流程定义
//        List<ProcessDefinition> list = this.processEngine.getRepositoryService().createProcessDefinitionQuery().processDefinitionId(flowableEvent1.getProcessDefinitionId()).list();
//        System.out.println(list);
//
//      } else if (flowableEvent instanceof FlowableEntityEventImpl) {
//        FlowableEntityEventImpl flowableEvent1 = (FlowableEntityEventImpl) flowableEvent;
//        logger.info("--> " + flowableEvent.getType() + " " + flowableEvent1.getExecutionId() + " " + flowableEvent1.getEntity());// Task
//
//        //获取流程定义
//        List<ProcessDefinition> list = this.processEngine.getRepositoryService().createProcessDefinitionQuery().processDefinitionId(flowableEvent1.getProcessDefinitionId()).list();
//        System.out.println(list);
//      }
//    }
//
//    if (flowableEvent.getType().equals(FlowableEngineEventType.PROCESS_COMPLETED)) {
//
//      logger.info("--> " + flowableEvent.getType() + " " + flowableEvent);
//    }

  }

  @Override
  public boolean isFailOnException() {
    /*
     * isFailOnException()方法决定了当事件分发后，onEvent(..)方法抛出异常时的行为。
     * 若返回false，忽略异常；若返回true，异常不会被忽略而会被上抛，使当前执行的命令失败。
     * true 才能异常才能回滚
     */
    return true;
  }

  @Override
  public boolean isFireOnTransactionLifecycleEvent() {
    return false;
  }

  @Override
  public String getOnTransaction() {
    return TransactionState.ROLLED_BACK.name();
  }

}
